<?php

class Vcode
{
    private $width; //宽
    private $height; //高
    private $num;  //数量
    private $code; //验证码
    private $img;  //图像的资源

    //构造方法， 三个参数
    function __construct($width = 200, $height = 200, $num = 4)
    {
        $this->width = $width;
        $this->height = $height;
        $this->num = $num;
        $this->code = $this->createcode(); //调用自己的方法
        $this->is = rand(0, ($num - 1));
    }

    //输出图像
    function outimg()
    {
        //创建背景 (颜色， 大小， 边框)
        $this->createback();
        //画字 (大小， 字体颜色)
        $this->outstring();
        //干扰元素(点， 线条)
        $this->setdisturbcolor();
        //输出图像
        $this->printimg();
    }

    //创建背景
    private function createback()
    {
        //创建资源
        $this->img = imagecreatetruecolor($this->width, $this->height);
        //设置随机的背景颜色
        $bgcolor = imagecolorallocate($this->img, rand(225, 255), rand(225, 255), rand(225, 255));
        //设置背景填充
        imagefill($this->img, 0, 0, $bgcolor);
        //画边框
        $bordercolor = imagecolorallocate($this->img, 0, 0, 0);

        imagerectangle($this->img, 0, 0, $this->width - 1, $this->height - 1, $bordercolor);
    }

    //画字
    private function outstring()
    {

        $arr = array();
        for ($i = 0; $i < $this->num; $i++)
        {

            $color = imagecolorallocate($this->img, rand(0, 128), rand(0, 128), rand(0, 128));

            $fontsize = rand(14, 18); //字体大小

            $x = ($this->width / $this->num) * $i; //水平位置
            if ($x > ($this->width - $fontsize * 3 - 10))
            {
                $x = $this->width - $fontsize * 3 - 20;
            }

            $y = rand(20, ($this->height - 5));
            //第几个汉字，汉字大小，坐标x，y,汉字值
            $arr[] = array('key' => $i, 'size' => $fontsize, 'x' => $x, 'y' => $y, 'code' => $this->code[$i]);

            //画出每个字符
            $fontfile = dirname(__FILE__) . '/../../public/fonts/simsun.ttf';
            imagettftext($this->img, $fontsize, '0', $x, $y, $color, $fontfile, $this->code[$i]);

            //imagechar($this->img, $fontsize, $x, $y, $this->code[$i], $color);
        }
        //存session
        $_SESSION['vcode'] = $arr[$this->is];
    }

    //设置干扰元素
    private function setdisturbcolor()
    {
        //加上点数
        for ($i = 0; $i < 100; $i++)
        {
            $color = imagecolorallocate($this->img, rand(0, 255), rand(0, 255), rand(0, 255));
            imagesetpixel($this->img, rand(1, $this->width - 2), rand(1, $this->height - 2), $color);
        }
        //加线条
        for ($i = 0; $i < 6; $i++)
        {
            $color = imagecolorallocate($this->img, rand(0, 255), rand(0, 128), rand(0, 255));
            imagearc($this->img, rand(-10, $this->width + 10), rand(-10, $this->height + 10), rand(30, 300), rand(30, 300), 55, 44, $color);
        }
    }

    //输出图像
    private function printimg()
    {
        if (imagetypes() & IMG_GIF)
        {
            header("Content-type: image/gif");
            imagegif($this->img);
        }
        elseif (function_exists("imagejpeg"))
        {
            header("Content-type: image/jpeg");
            imagegif($this->img);
        }
        elseif (imagetypes() & IMG_PNG)
        {
            header("Content-type: image/png");
            imagegif($this->img);
        }
        else
        {
            die("No image support in this PHP server");
        }
    }

    //生成验证码字符串
    private function createcode()
    {
        $codes = array(
            '兄', '弟', '姐', '妹', '危', '困', '助', '帮', '姑', '姨', '叔', '舅', '亲', '戚', '互', '访',
            '侄', '男', '闺', '少', '哺', '育', '茁', '壮', '夫', '妻', '相', '敬', '梦', '忆', '糟', '糠',
            '隔', '屋', '邻', '舍', '遇', '事', '谦', '谅', '伯', '公', '妪', '婆', '慈', '孝', '赡', '养',
            '尊', '朋', '礼', '友', '仁', '义', '君', '郎', '炎', '黄', '二', '帝', '尧', '舜', '禅', '让',
            '禹', '启', '世', '袭', '灭', '桀', '商', '汤', '周', '武', '伐', '纣', '侯', '列', '各', '邦',
            '秦', '皇', '集', '权', '汉', '刘', '楚', '项', '鼎', '立', '割', '据', '乱', '晋', '八', '王',
            '南', '北', '对', '峙', '腐', '朽', '隋', '炀', '贞', '观', '政', '要', '五', '代', '续', '唐',
            '陈', '桥', '兵', '变', '耻', '辱', '靖', '康', '耶', '律', '完', '颜', '元', '建', '宋', '僵',
            '钟', '离', '太', '祖', '崇', '祯', '吊', '丧', '清', '军', '入', '关', '大', '臣', '驻', '藏',
            '粉', '碎', '叛', '卓', '犁', '域', '设', '将', '台', '湾', '复', '归', '守', '卫', '边', '防',
            '鸦', '片', '战', '争', '英', '占', '香', '港', '戊', '戌', '维', '新', '社', '会', '改', '良',
            '辛', '亥', '革', '命', '孙', '文', '思', '想', '联', '盟', '抗', '倭', '国', '共', '两', '党',
            '定', '都', '京', '师', '人', '民', '解', '放', '诸', '子', '百', '家', '孔', '孟', '老', '庄',
            '扁', '鹊', '灵', '医', '鲁', '班', '巧', '匠', '罗', '盘', '硝', '药', '针', '灸', '疗', '伤',
            '蔡', '伦', '毕', '升', '鉴', '真', '玄', '奘', '易', '经', '论', '语', '史', '记', '达', '畅',
            '河', '图', '洛', '书', '算', '术', '九', '章', '西', '三', '红', '水', '聊', '儒', '瓶', '厢',
            '诗', '词', '曲', '赋', '戏', '剧', '说', '唱', '琵', '琶', '琴', '瑟', '锣', '镲', '铿', '锵',
            '笙', '箫', '呜', '咽', '卧', '笛', '悠', '扬', '筝', '音', '奔', '奋', '唢', '呐', '高', '亢',
            '荆', '浩', '匡', '庐', '董', '源', '潇', '湘', '米', '芾', '写', '意', '悲', '鸿', '骏', '昂',
            '笔', '墨', '纸', '砚', '匾', '楣', '楹', '榜', '楷', '隶', '篆', '刻', '碑', '帖', '草', '狂',
            '敦', '煌', '石', '窟', '长', '城', '伟', '墙', '青', '铜', '甲', '骨', '缕', '衣', '纱', '裳',
            '虎', '符', '越', '剑', '陶', '马', '俑', '葬', '彩', '瓷', '宝', '瓮', '丝', '绸', '他', '乡',
            '凡', '尔', '赛', '宫', '金', '字', '塔', '状', '泰', '姬', '陵', '墓', '彼', '得', '教', '堂',
            '自', '由', '女', '神', '希', '腊', '塑', '像', '最', '后', '晚', '餐', '创', '造', '亚', '当',
            '亭', '榭', '楼', '阁', '寺', '庙', '殿', '廊', '蓬', '门', '荜', '户', '丈', '室', '绿', '窗',
            '府', '弟', '别', '墅', '画', '栋', '雕', '梁', '庭', '院', '踏', '步', '影', '屏', '幕', '障',
            '承', '尘', '藻', '井', '篱', '笆', '柱', '桩', '舷', '舵', '扶', '靠', '凭', '栏', '眺', '望');
        $code = array();
        $arr = array();
        for ($i = 0; $i < $this->num; $i++)
        {
            $code3 = '';
            for ($j = 0; $j < 3; $j++)
            {
                $key = rand(0, (count($codes) - 1));
                $code3 .= $codes[$key];
                unset($codes[$key]);
                $newarr = array();
                foreach ($codes as $val)
                {
                    $newarr[] = $val;
                }
                $codes = $newarr;
            }
            $code[] = $code3;
        }
        return $code;
    }

    //用于自动销毁图像资源
    function __destruct()
    {
        $this->img && imagedestroy($this->img);
    }
}
